package com.itxuhang.mvc.adapter;

import com.itxuhang.mvc.annotation.ResponseBody;
import com.itxuhang.mvc.converter.IntegerTypeHandler;
import com.itxuhang.mvc.converter.StringTypeHandler;
import com.itxuhang.mvc.converter.TypeHandler;
import com.itxuhang.mvc.handler.HandlerMethod;
import com.itxuhang.mvc.model.ModelAndView;
import com.itxuhang.mvc.utils.JsonUtils;
import com.itxuhang.spring.init.InitializingBean;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class RequestMappingHandlerAdapter implements HandlerAdapter, InitializingBean {
    private List<TypeHandler> typeHandlers = new ArrayList<>();

    @Override
    public boolean supports(Object handler) {
        return handler instanceof HandlerMethod;
    }

    @Override
    public ModelAndView handleRequest(Object handler, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        HandlerMethod hm = (HandlerMethod) handler;
        Object controller = hm.getController();
        Method method = hm.getMethod();

        // 处理请求参数
        Object[] args = handleParameters(method,request);

        try {
            Object returnValue = method.invoke(controller,args);

            // 处理返回值
            handleReturnValue(method,returnValue,response);

        }catch (Exception e){
          e.printStackTrace();
        }

        return null;
    }

    private void handleReturnValue(Method method, Object returnValue, HttpServletResponse response) throws IOException{
        if (method.isAnnotationPresent(ResponseBody.class)){
            if (returnValue instanceof String){
                response.setContentType("text/plain;charset=utf-8");
                response.getWriter().write(returnValue.toString());
            }else{
                // 返回的是对象类型
                response.setContentType("application/json;charset=utf-8");
                response.getWriter().write(JsonUtils.object2Json(returnValue));
            }

        }else{
            // 处理视图
        }

    }

    private Object[] handleParameters(Method method, HttpServletRequest request) {
        // 获取请求中的KV集合
        Map<String, String[]> parameterMap = request.getParameterMap();

        // Controller类中方法的参数集合
        Parameter[] parameters = method.getParameters();

        // 存放转换之后的参数值
        List<Object> argList = new ArrayList<>();

        for (Parameter parameter : parameters) {
            // 方法参数名称
            String name = parameter.getName();
            Class<?> type = parameter.getType();

            // 从请求集合中获取到的所有的值的类型，都是String类型
            String[] values = parameterMap.get(name);

            Object valueToUse = resolveValue(values,type);

            argList.add(valueToUse);
        }


        return argList.toArray();
    }

    private Object resolveValue(String[] values, Class<?> type) {
        if (values == null || values.length == 0 ) {
            return null;
        }
        for (TypeHandler handler : typeHandlers) {
            if(handler.supports(type)){
                return handler.resoleValue(values);
            }
        }
        return null;
    }


    @Override
    public void afterPropertiesSet() {
        typeHandlers.add(new IntegerTypeHandler());
        typeHandlers.add(new StringTypeHandler());
    }
}
